package de.XPortLib;


import java.io.IOException;

import de.XPortLib.Exceptions.TCPCommunicationException;



/**
 * @author olz
 * 
 * TODO To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Generation - Code and Comments
 */
/**
 * This class will be responsible for all sorts of I/O and LED controls.
 * 
 * @author olz
 * 
 * TODO To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Generation - Code and Comments
 */
public class IOControl {

    /**
     * this static byte contains a value to select all the XPort's LEDs( decimal
     * 7 = bin 00000111; Bits 0 to 2 are set
     */
    private static final byte maxLEDLo = (byte) 0xFF; // new for WiPort, really
                                                      // 7;

    private static final byte maxLEDHi = 0x07; // noch! :) 7;

    /**
     * this static int states the port on which the XPort's I/O settings are
     * changed
     */
    private static final int IOPort = 0x77f0;

    /** this static int states the length of an XPort's answer in bytes */
    private static final int cmdLength = 5; // was 9 = Wrong! --plymo-- 26.12.2004

    // XPort Commands fixed as bytes
    /** this static byte is set to the value of GetFunction 
     * Checks which Pins are availbale to user and not used for RTS and Co.
     * */
    private static final byte cmdGetFunc = 0x10;

    /** this static byte is set to the value of GetDirections */
    private static final byte cmdGetDir = 0x11;

    /** this static byte is set to the value of Get Active Levels */
    private static final byte cmdGetActLvl = 0x12;

    /** this static byte is set to the value of Get Current State */
    private static final byte cmdGetCurrState = 0x13;

    /** this static byte is set to the value of Set Direction */
    private static final byte cmdSetDir = 0x19;

    /** this static byte is set to the value of Set Active Level */
    private static final byte cmdsetActLvl = 0x1a;

    /** this static byte is set to the value of Set Current State */
    private static final byte cmdSetCurrState = 0x1b;

    /** initialisation of variable antwort, which will return the XPort's antwort */
    byte[] antwort = { 0, 0, 0, 0, 0 };

    /**
     * initialisation of variable antwort_null, which be used to reset antwort.
     * In case of errors, antwort will remain 0,0,0,0,0 so that error handling
     * is possible
     */
    byte[] antwort_null = { 0, 0, 0, 0, 0 };

    /** this instance will control the XPort for this class */
    private Communication XPort1;

    /**
     * this method will read out and return the current states of the I/O pins
     * 
     * @param ipa
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] getActiveLevel(String ipa) throws TCPCommunicationException {

        int[] command = { cmdGetActLvl, 0, 0, 0, 0, // no parameters needed
                0, 0, 0, 0 };
        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;
    }

    /**
     * this method will switch the I/O pins' directions according to the
     * parameter
     * 
     * @param ipa
     * @param NumLed
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] toggleDirection(String ipa, int NumLed) throws TCPCommunicationException {

        int[] command = { cmdSetDir, maxLEDLo, maxLEDHi, 0, 0,
                (byte) (NumLed & maxLEDLo), (byte) ((NumLed >> 8) & maxLEDHi), 0, 0 };

        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;
    }

    /**
     * will read out and return the I/O pins' current states
     * 
     * @param ipa
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] getCurrentState(String ipa) throws TCPCommunicationException{
        int[] command = { cmdGetCurrState, 0, 0, 0, 0, // no parameters needed
                0, 0, 0, 0 };
        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;

    }

    /**
     * will establish a connection according to the parameters ipa and port
     * 
     * @param ipa
     * @param port
     * @throws IOException
     * @throws Exception
     */
    public void connectLED(String ipa, int port) throws TCPCommunicationException {
        XPort1 = new Communication(); // preparing a new connection
        XPort1.connect(ipa, port);
        // connecting to new XPort instance on LED switching port
    }

    /**
     * will toggle LEDs on and off acccording to its parameter's value
     * 
     * @param ipa - IPAddress
     * @param NumLed - Bit-Coded which LED to turn ON or OFF 
     * @return - antwort array ob 5 bytes
     * @throws IOException
     * @throws Exception
     */
    public byte[] toggle(String ipa, int NumLed) throws TCPCommunicationException {

        byte ValueLedLo = 0;
        byte ValueLedHi = 0;
        ValueLedLo = (byte) NumLed;
        ValueLedHi = (byte) (NumLed >> 8);
        System.out.println("Toggle Anfang");
        int[] command = { cmdSetCurrState, maxLEDLo, maxLEDHi, 0, 0, // maxLED
                                                                      // sets
                                                                      // all
                                                                      // LEDs
                                                                      // ready
                                                                      // for
                                                                      // change
                ValueLedLo, ValueLedHi, 0, 0 }; // toggles the LEDs on / off
                                                // according to the value
        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;
    }

    /**
     * will connect to the XPort located at the IP ipa and the port port, then
     * send a command as given in command[], end the connection and return the
     * answer
     * 
     * @param ipa
     * @param port
     * @param command
     * @param length
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] sendCommand(String ipa, int port, int[] command, int length)
            throws TCPCommunicationException {
        connectLED(ipa, port);
        XPort1.send(command);
        antwort = (XPort1.receiveByteArray(length));
        XPort1.disconnect();
        return antwort;
    }

    /**
     * will receive the number of I/O pins available on the XPort
     * 
     * @param ipa
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] getFunc(String ipa) throws TCPCommunicationException {

        int[] command = { cmdGetFunc, 0, 0, 0, 0, // no paramters needed
                0, 0, 0, 0 };
        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;

    }

    /**
     * reads the I/O pins' directions from the XPort and returns them
     * 
     * @param ipa
     * @return
     * @throws IOException
     * @throws Exception
     */
    public byte[] getDir(String ipa) throws TCPCommunicationException {

        //System.out.println("ToggleOn Anfang");
        int[] command = { cmdGetDir, 0, 0, 0, 0, 0, 0, 0, 0 };
        antwort = antwort_null;
        antwort = sendCommand(ipa, IOPort, command, cmdLength);
        return antwort;
    }
}
